//
// Created by syj on 2024/3/14.
//

#ifndef TRANSMIDDLE_TYPES_H
#define TRANSMIDDLE_TYPES_H

#include <cxxabi.h>
#include <stdint.h>

#include <chrono>
#include <future>
#include <string>
#include <type_traits>

namespace core{

#define ENABLE_AND_FOR_ENUM(E)                                      \
  inline E operator&(const E lhs, const E rhs) {                    \
    return (static_cast<E>(                                         \
        static_cast<typename std::underlying_type<E>::type>(lhs) &  \
        static_cast<typename std::underlying_type<E>::type>(rhs))); \
  }

#define ENABLE_OR_FOR_ENUM(E)                                       \
  inline E operator|(const E lhs, const E rhs) {                    \
    return (static_cast<E>(                                         \
        static_cast<typename std::underlying_type<E>::type>(lhs) |  \
        static_cast<typename std::underlying_type<E>::type>(rhs))); \
  }

#define ENABLE_COMPIRE_FOR_ENUM(E)                                           \
  inline bool operator!=(const E lhs, const std::underlying_type_t<E> rhs) { \
    return static_cast<std::underlying_type_t<E>>(lhs) != rhs;               \
  }                                                                          \
  inline bool operator==(const E lhs, const std::underlying_type_t<E> rhs) { \
    return !(lhs != rhs);                                                    \
  }                                                                          \
  inline bool operator!=(const std::underlying_type_t<E> lhs, const E rhs) { \
    return lhs != static_cast<std::underlying_type_t<E>>(rhs);               \
  }                                                                          \
  inline bool operator==(const std::underlying_type_t<E> lhs, const E rhs) { \
    return !(lhs != rhs);                                                    \
  }

    /* 运算符重载宏 */
#define SUPPORT_ENUM_AS_FLAG(E) \
  ENABLE_AND_FOR_ENUM(E)        \
  ENABLE_OR_FOR_ENUM(E)         \
  ENABLE_COMPIRE_FOR_ENUM(E)

    /** 通用令牌类型 */
//    using token_t = std::uint64_t;

    /** 空令牌 */
//    static constexpr token_t token_null = 0;
//    static constexpr token_t nulltoken = token_null;

    /**
     * 将指定类型转换为字符串
     */
    template <typename T>
    std::string stringify(T const& value);

    /**
     * 将字符串转换为指定类型
     */
    template <typename T>
    T parse(std::string const& value);

    /**
     * 获取类型限定名
     */
    template <typename T>
    const char* QualifiedName() {
        static auto const name = abi::__cxa_demangle(typeid(std::decay_t<T>).name(),
                                                     nullptr, nullptr, nullptr);
        return name;
    }

    /**
     * future 状态
     */
    enum class FutureStatus {
        kPending,
        kResolved,
        kRejected,

        kTimeout = kPending
    };

    /**
     * 获取 future 状态
     */
    template <typename T>
    inline FutureStatus status(std::shared_future<T> const& future) {
        if (future.wait_for(std::chrono::seconds(0)) == std::future_status::timeout)
            return FutureStatus::kPending;
        try {
            (void)future.get();
            return FutureStatus::kResolved;
        } catch (...) {
            return FutureStatus::kRejected;
        }
    }

    /** 等待状态 */
    enum class WaitStatus { kNotified, kTimeout };
}

#endif //TRANSMIDDLE_TYPES_H
